﻿using System;
using System.Collections.Generic;
using System.Threading;
using SweeperPrototype.Business;
using SweeperPrototype.Business.Fields;
using SweeperPrototype.Business.Keys;
using SweeperPrototype.Business.Plumbing.Requests;

namespace SweeperPrototype.Objects
{
    public class PositionProvider : NotifyList<PositionSubscription>
    {
        private Dictionary<PositionSubscription.UniqueKey, PositionSubscription> m_Positions;
        private Dictionary<BookCode, NotifyList<PositionSubscription>> m_PositionLookup;
        private PositionRequestManager m_RequestManager;

        public PositionProvider(PositionRequestManager request_manager)
        {
            m_PositionLookup = new Dictionary<BookCode, NotifyList<PositionSubscription>>();
            m_RequestManager = request_manager;
            m_Positions = new Dictionary<PositionSubscription.UniqueKey, PositionSubscription>();
        }


        public PositionSubscription this[ PositionSubscription.UniqueKey key ]
        {
            get { return m_Positions[key]; }
        }


        public PositionSubscription Subscribe(BookCode book, ExposureRIC ric )
        {
            PositionSubscription.UniqueKey key = new PositionSubscription.UniqueKey(book, ric);
            return Subscribe( key );
        }

        public PositionSubscription Subscribe(PositionSubscription.UniqueKey key)
        {
            PositionSubscription position_subscription;
            if (m_Positions.TryGetValue(key, out position_subscription) == false)
            {
                position_subscription = CreatePosition(key.BookCode, key.RIC);
                m_Positions.Add(key, position_subscription);
                m_PositionLookup.Add(key.BookCode, new NotifyList<PositionSubscription>());
            }
            return position_subscription;
        }

        public NotifyList<PositionSubscription> Subscribe( BookCode code )
        {
            NotifyList<PositionSubscription> positions;
            if( m_PositionLookup.TryGetValue( code, out positions ) == false )
            {
                positions = m_RequestManager.Subscribe(code);
                positions.Addition += HandleAddition;
                positions.Removal += HandleRemoval;
                m_PositionLookup.Add( code, positions );
            }
            return positions;
        }

        private void HandleRemoval(PositionSubscription removal, int index)
        {
            PositionSubscription.UniqueKey key = new PositionSubscription.UniqueKey(removal.BookCode, removal.RIC);
            m_Positions[key].Update( new PositionSubscription.PositionUpdate(new Shares(0), new Timestamp( DateTime.Now ) ) );
            Remove( removal );
        }

        private void HandleAddition(PositionSubscription addition, int index)
        {
            m_Positions.Add( new PositionSubscription.UniqueKey(addition.BookCode, addition.RIC), addition );
            Add( addition );
        }


        private NotifyList<PositionSubscription> CreateNotifyList( BookCode code )
        {
            NotifyList<PositionSubscription> list = m_RequestManager.Subscribe(code);
            
            return list;
        }

        private PositionSubscription CreatePosition( BookCode code, ExposureRIC ric )
        {
            throw new NotSupportedException();
            PositionSubscription position_subscription = new PositionSubscription( code, ric );
            //m_RequestManager.Subscribe( new PositionSubscription.UniqueKey(code, ric),
            //                            position_subscription.Update );
            return position_subscription;
        }

    }
}